package org.aldar.bquest.entity.pool;

import android.util.Log;
import org.aldar.bquest.constants.LandscapeType;
import org.aldar.bquest.constants.TileState;
import org.aldar.bquest.entity.AbilityTileSprite;
import org.aldar.bquest.entity.BigCrystalTileSprite;
import org.aldar.bquest.entity.CrystalTileSprite;
import org.aldar.bquest.entity.TileSprite;
import org.aldar.bquest.logic.controller.level.LevelController;
import org.aldar.bquest.profile.GameProfile;
import org.aldar.bquest.resources.ResourceManager;
import org.aldar.bquest.screens.MainBoardScreen;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.TiledSprite;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * User: Daria
 * Date: 6/13/13 10:58 PM
 */
public class TilesPool {

    static Map<LandscapeType, Stack<TileSprite>> tilesPool = new HashMap<LandscapeType, Stack<TileSprite>>();

    static Map<Object, Stack<Sprite>> entitiesPool = new HashMap<Object, Stack<Sprite>>();

    static int createdTiles = 0;

    static int createdObjects = 0;

    static int createdAbilityTiles = 0;

    public static void printCount() {
        int tilesCount = 0;
        int entitiesCount = 0;
        for (Object o : entitiesPool.keySet()) {
            entitiesCount += entitiesPool.get(o).size();
        }
        for (LandscapeType o : tilesPool.keySet()) {
            tilesCount += tilesPool.get(o).size();
        }
        //Log.i("aldar","EntityPool stats: tiles: "+tilesCount+" entities "+entitiesCount);
        Log.i("aldar", "EntityPool creation stats: tiles: " + createdTiles + " entities " + createdObjects + " abilities " + createdAbilityTiles);

    }

    public static synchronized TileSprite getSpriteForStyle(LandscapeType style, int col, int row) {
        Stack<TileSprite> styleStack = tilesPool.get(style);
        if (styleStack != null && styleStack.size() > 0) {
            return styleStack.pop();
        }
        TileSprite newSprite = null;
        if (style == LandscapeType.CRYSTAL) {
            newSprite = new CrystalTileSprite(col, row, ResourceManager.getInstance().getMagicTileTextureRegion(), MainBoardScreen.getScm().getVertexBufferObjectManager());
        } else if (style == LandscapeType.BIGCRYSTAL) {
            newSprite = new BigCrystalTileSprite(col, row, ResourceManager.getInstance().getCristalBigRegion(), MainBoardScreen.getScm().getVertexBufferObjectManager());
        } else {
            newSprite = new TileSprite(col, row, ResourceManager.getInstance().getTileTextureRegion(style), MainBoardScreen.getScm().getVertexBufferObjectManager());
        }
        createdTiles++;
        newSprite.setStyle(style);
        return newSprite;
    }

    public static void clearPool() {
        tilesPool = new HashMap<LandscapeType, Stack<TileSprite>>();
    }

    public static synchronized void pushToStack(TileSprite tile) {
        Stack<TileSprite> styleStack = tilesPool.get(tile.getStyle());
        tile.setState(TileState.STATE_NORMAL);
        if (styleStack == null) {
            styleStack = new Stack<TileSprite>();
            tile.getTile().setScale(1);
            tilesPool.put(tile.getStyle(), styleStack);
        }
        styleStack.push(tile);
    }

    public static synchronized Sprite getEntityForTexture(ITextureRegion textureRegion, VertexBufferObjectManager vertexBufferObjectManager) {
        Stack<Sprite> entityStack = entitiesPool.get(textureRegion);
        if (entityStack != null && entityStack.size() > 0) {
            return entityStack.pop();
        }
        Sprite newSprite = null;
        if (textureRegion instanceof ITiledTextureRegion) {
            ITiledTextureRegion tiledRegion = (ITiledTextureRegion) textureRegion;
            newSprite = new TiledSprite(0, 0, tiledRegion.getWidth(), tiledRegion.getHeight(), tiledRegion, vertexBufferObjectManager);
        } else {
            newSprite = new Sprite(0, 0, textureRegion.getWidth(), textureRegion.getHeight(), textureRegion, vertexBufferObjectManager);
        }
        createdObjects++;
        return newSprite;
    }

    public static synchronized Sprite getEntityForTexture(ITextureRegion textureRegion) {
        return getEntityForTexture(textureRegion, MainBoardScreen.getScm().getVertexBufferObjectManager());
    }

    public static synchronized TiledSprite getEntityForTiledTexture(ITiledTextureRegion textureRegion) {
        return (TiledSprite) getEntityForTexture(textureRegion);
    }


    public static synchronized void pushEntityToStack(Sprite entity) {
        Stack<Sprite> entityStack = entitiesPool.get(entity.getTextureRegion());
        if (entityStack == null) {
            entityStack = new Stack<Sprite>();
            entitiesPool.put(entity.getTextureRegion(), entityStack);
        }
        entity.setScale(1f);
        entity.setAlpha(1f);
        entityStack.push(entity);
    }


    public static TileSprite getSpriteForCrystalTile(int col, int row) {
        CrystalTileSprite crystalTile = (CrystalTileSprite) getSpriteForStyle(LandscapeType.CRYSTAL, col, row);
        crystalTile.restartAnimation();
        return crystalTile;
    }

    public static TileSprite getSpriteForBigCrystalTile(int col, int row) {
        BigCrystalTileSprite bigCrysalTile = (BigCrystalTileSprite) getSpriteForStyle(LandscapeType.BIGCRYSTAL, col, row);
        bigCrysalTile.restartAnimation();
        return bigCrysalTile;
    }

    public static TileSprite getSpriteForAbilityTile(int col, int row) {
        LandscapeType style = LandscapeType.CRYSTAL_ABILITY;
        AbilityTileSprite tileSprite = null;
        boolean isCurrentTown = LevelController.getTimeLine().getCurrentLandscape().getLandscapeType().allowsConcerts() == true;

        boolean concertsRemain = false;
        int reachedTownIndex = GameProfile.getCurrentLevelProfile().getReachedTownIndex();
        if (reachedTownIndex >= 0 && GameProfile.getCurrentLevelProfile().getRemainingConcertsByTown().get(reachedTownIndex) > 0) {
            concertsRemain = true;
        }
        ;
        if (isCurrentTown && concertsRemain) {
            tileSprite = AbilityTileSprite.getPlayConcertTileSprite(col, row);
        } else {
            tileSprite = AbilityTileSprite.getRandomAbilityTileSprite(col, row);
        }
        createdAbilityTiles++;
        tileSprite.setStyle(style);
        tileSprite.restartAnimation();
        return tileSprite;

    }

}
